home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / ZAP.C < prev   
C/C++ Source or Header  |  1993-03-16  |  53KB  |  2,211 lines

  1. /*    SCCS Id: @(#)zap.c    3.0    89/11/08
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. #if defined(ALTARS) && defined(THEOLOGY)
  8. static boolean NEARDATA priesthit = FALSE;
  9. #endif
  10.  
  11. static int FDECL(burn_floor_paper,(int,int));
  12. STATIC_PTR int FDECL(bhitm,(struct monst *,struct obj *));
  13. static void FDECL(cancel_item,(struct obj *));
  14. static int FDECL(bhitgold,(struct gold *,struct obj *));
  15. STATIC_PTR int FDECL(bhito,(struct obj *,struct obj *));
  16. static void FDECL(backfire,(struct obj *));
  17. static uchar FDECL(dirlet,(int,int));
  18. static int FDECL(zhit,(struct monst *,int,int));
  19.  
  20. const char *fl[]= {
  21.     "magic missile",    /* Wands must be 0-9 */
  22.     "bolt of fire",
  23.     "sleep ray",
  24.     "bolt of cold",
  25.     "death ray",
  26.     "bolt of lightning",
  27.     "",
  28.     "",
  29.     "",
  30.     "",
  31.  
  32.     "magic missile",    /* Spell equivalents must be 10-19 */
  33.     "fireball",
  34.     "sleep ray",
  35.     "cone of cold",
  36.     "finger of death",
  37.     "bolt of lightning",
  38.     "",
  39.     "",
  40.     "",
  41.     "",
  42.  
  43.     "blast of missiles",    /* Dragon breath equivalents 20-29*/
  44.     "blast of fire",
  45.     "blast of sleep gas",
  46.     "blast of frost",
  47.     "blast of disintegration",
  48.     "blast of lightning",
  49.     "blast of poison gas",
  50.     "blast of acid",
  51.     "",
  52.     ""
  53. };
  54.  
  55. #ifdef TEXTCOLOR
  56. static const int zapcolor[10] = {
  57.     AT_ZAP, RED|BRIGHT, AT_ZAP, WHITE|BRIGHT, AT_ZAP, WHITE|BRIGHT,
  58.     AT_ZAP, AT_ZAP, AT_ZAP, AT_ZAP
  59. };
  60. #endif
  61.  
  62. /* Routines for IMMEDIATE wands and spells. */
  63. /* bhitm: monster mtmp was hit by the effect of wand or spell otmp */
  64. STATIC_PTR
  65. int
  66. bhitm(mtmp, otmp)
  67. register struct monst *mtmp;
  68. register struct obj *otmp;
  69. {
  70.     wakeup(mtmp);
  71.     switch(otmp->otyp) {
  72.     case WAN_STRIKING:
  73. #ifdef SPELLS
  74.     case SPE_FORCE_BOLT:
  75. #endif
  76.         if(u.uswallow || rnd(20) < 10+mtmp->data->ac) {
  77.             register int tmp = d(2,12);
  78.             hit((otmp->otyp == WAN_STRIKING) ? "wand" : "spell", mtmp, exclam(tmp));
  79.             (void) resist(mtmp, otmp->olet, tmp, TELL);
  80.         } else miss((otmp->otyp == WAN_STRIKING) ? "wand" : "spell", mtmp);
  81.         break;
  82.     case WAN_SLOW_MONSTER:
  83. #ifdef SPELLS
  84.     case SPE_SLOW_MONSTER:
  85. #endif
  86.         if(! resist(mtmp, otmp->olet, 0, NOTELL)) {
  87.             if (mtmp->mspeed == MFAST) mtmp->mspeed = 0;
  88.             else mtmp->mspeed = MSLOW;
  89.             if (u.uswallow && (mtmp == u.ustuck) && 
  90.                 is_whirly(mtmp->data)) {
  91.                 You("disrupt %s!", mon_nam(mtmp));
  92.                 pline("A huge hole opens up...");
  93.                 expels(mtmp, mtmp->data, TRUE);
  94.             }
  95.         }
  96.         break;
  97.     case WAN_SPEED_MONSTER:
  98.         if (!resist(mtmp, otmp->olet, 0, NOTELL))
  99.             if (mtmp->mspeed == MSLOW) mtmp->mspeed = 0;
  100.             else mtmp->mspeed = MFAST;
  101.         break;
  102.     case WAN_UNDEAD_TURNING:
  103. #ifdef SPELLS
  104.     case SPE_TURN_UNDEAD:
  105. #endif
  106.         if(is_undead(mtmp->data)) {
  107.  
  108.             if(!resist(mtmp, otmp->olet, rnd(8), NOTELL))
  109.                 mtmp->mflee = 1;
  110.         }
  111.         break;
  112.     case WAN_POLYMORPH:
  113. #ifdef SPELLS
  114.     case SPE_POLYMORPH:
  115. #endif
  116.         if(!resist(mtmp, otmp->olet, 0, NOTELL))
  117.             if( newcham(mtmp, (struct permonst *)0) )
  118.             if (!Hallucination)
  119.                 makeknown(otmp->otyp);
  120.         break;
  121.     case WAN_CANCELLATION:
  122. #ifdef SPELLS
  123.     case SPE_CANCELLATION:
  124. #endif
  125.         if(!resist(mtmp, otmp->olet, 0, NOTELL)) {
  126.           if (is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN)
  127.             were_change(mtmp);
  128. #ifdef GOLEMS
  129.           if (mtmp->data == &mons[PM_CLAY_GOLEM]) {
  130.             if (!Blind)
  131.               pline("Some writing vanishes from %s's head!",
  132.             mon_nam(mtmp));
  133.             killed(mtmp);
  134.           }
  135.           else
  136. #endif /* GOLEMS */
  137.             mtmp->mcan = 1;
  138.         }
  139.         break;
  140.     case WAN_TELEPORTATION:
  141. #ifdef SPELLS
  142.     case SPE_TELEPORT_AWAY:
  143. #endif
  144. #if defined(ALTARS) && defined(THEOLOGY)
  145.         if(mtmp->ispriest && in_temple(mtmp->mx, mtmp->my)) {
  146.             kludge("%s resists your magic!", Monnam(mtmp));
  147.             wakeup(mtmp);
  148.             break;
  149.         }
  150. #endif
  151.         rloc(mtmp);
  152.         break;
  153.     case WAN_MAKE_INVISIBLE:
  154.         mtmp->minvis = 1;
  155.         break;
  156.     case WAN_NOTHING:
  157.         break;
  158. #ifdef PROBING
  159.     case WAN_PROBING:
  160.         makeknown(otmp->otyp);
  161.         mstatusline(mtmp);
  162.         break;
  163. #endif
  164.     case WAN_OPENING:
  165.         if(u.uswallow && mtmp == u.ustuck) {
  166.             if (is_animal(mtmp->data)) {
  167.                 if (Blind) pline("Its mouth opens!");
  168.                 else pline("%s opens its mouth!", Monnam(mtmp));
  169.             }
  170.             expels(mtmp, mtmp->data, TRUE);
  171.             break;
  172.         }
  173.     case WAN_LOCKING:
  174. #ifdef SPELLS
  175.     case SPE_KNOCK:
  176.     case SPE_WIZARD_LOCK:
  177. #endif
  178.         break;
  179.     default:
  180.         impossible("What an interesting effect (%u)", otmp->otyp);
  181.     }
  182.     return 0;
  183. }
  184.  
  185. struct monst *
  186. revive(obj,ininv)
  187. register struct obj *obj;
  188. boolean ininv;
  189. {
  190.     register struct monst *mtmp = (struct monst *)0;
  191.  
  192.     if(obj->otyp == CORPSE) {
  193.         int montype = obj->corpsenm;
  194.         int x = ininv ? u.ux : obj->ox;
  195.         int y = ininv ? u.uy : obj->oy;
  196.  
  197.         if (cant_create(&montype)) { /* will make zombie instead */
  198.             mtmp = makemon(&mons[PM_HUMAN_ZOMBIE], x, y);
  199.             if (mtmp) {
  200.                 mtmp->mhp = mtmp->mhpmax = 100;
  201.                 mtmp->mspeed = MFAST;
  202.             }
  203.         } else {
  204.             struct obj *otmp;
  205. #ifdef ARMY
  206.             if (is_mercenary(&mons[montype]))
  207.                 montype = PM_UNARMORED_SOLDIER;
  208. #endif
  209.             mtmp = makemon(&mons[montype], x, y);
  210.             if (mtmp) {
  211.                 /* Monster retains its name */
  212.                 if (obj->onamelth)
  213.                     mtmp = christen_monst(mtmp, ONAME(obj));
  214.                 /* No inventory for newly revived monsters */
  215.                 while(otmp = (mtmp->minvent)) {
  216.                     mtmp->minvent = otmp->nobj;
  217.                     free((genericptr_t)otmp);
  218.                 }
  219.             }
  220.         }
  221.         if (mtmp && obj->oeaten)
  222.             mtmp->mhp = eaten_stat(mtmp->mhp, obj);
  223.         if (ininv) useup(obj);
  224.         else {
  225.             /* not useupf(), which charges */
  226.             if (obj->quan > 1) obj->quan--;
  227.             else delobj(obj);
  228.         }
  229.         if (x != u.ux || y != u.uy || Invisible)
  230.             newsym(x, y);
  231.     }
  232.     return mtmp;
  233. }
  234.  
  235. static const char NEARDATA charged_objs[] = { WAND_SYM, WEAPON_SYM, ARMOR_SYM, 0 };
  236.  
  237. static void
  238. cancel_item(obj)
  239. register struct obj *obj;
  240. {
  241.     switch(obj->otyp) {
  242.         case RIN_GAIN_STRENGTH:
  243.             if(obj->owornmask & W_RING) {
  244.                 ABON(A_STR) -= obj->spe;
  245.                 flags.botl = 1;
  246.             }
  247.             break;
  248.         case RIN_ADORNMENT:
  249.             if(obj->owornmask & W_RING) {
  250.                 ABON(A_CHA) -= obj->spe;
  251.                 flags.botl = 1;
  252.             }
  253.             break;
  254.         case RIN_INCREASE_DAMAGE:
  255.             if(obj->owornmask & W_RING)
  256.                 u.udaminc -= obj->spe;
  257.             break;
  258.         case GAUNTLETS_OF_DEXTERITY:
  259.             if(obj->owornmask & W_ARMG) {
  260.                 ABON(A_DEX) -= obj->spe;
  261.                 flags.botl = 1;
  262.             }
  263.             break;
  264.         case HELM_OF_BRILLIANCE:
  265.             if(obj->owornmask & W_ARMH) {
  266.                 ABON(A_INT) -= obj->spe;
  267.                 ABON(A_WIS) -= obj->spe;
  268.                 flags.botl = 1;
  269.             }
  270.             break;
  271.         /* case RIN_PROTECTION: /* not needed */
  272.     }
  273.     if(obj->spe &&
  274.       !(obj->otyp == AMULET_OF_YENDOR ||
  275.         obj->otyp == WAN_CANCELLATION || /* can't cancel cancellation */
  276.         obj->otyp == TIN || obj->otyp == EGG ||
  277.         obj->otyp == STATUE ||
  278. #ifdef MAIL
  279.         obj->otyp == SCR_MAIL ||
  280. #endif
  281. #ifdef TUTTI_FRUTTI
  282.         obj->otyp == SLIME_MOLD ||
  283. #endif
  284.         obj->otyp == KEY || obj->otyp == SKELETON_KEY ||
  285.         obj->otyp == LARGE_BOX || obj->otyp == CHEST))
  286.         obj->spe = (obj->olet == WAND_SYM) ? -1 : 0;
  287.  
  288.     if (obj->olet == SCROLL_SYM
  289. #ifdef MAIL
  290.         && obj->otyp != SCR_MAIL
  291. #endif
  292.        )
  293.         obj->otyp = SCR_BLANK_PAPER;
  294.  
  295.     if (obj->olet == POTION_SYM && obj->otyp > POT_BOOZE)
  296.         obj->otyp = (obj->otyp==POT_SICKNESS || obj->otyp==POT_SEE_INVISIBLE) ? POT_FRUIT_JUICE : POT_WATER;
  297.         /* sickness is "biologically contaminated" fruit juice; cancel it
  298.          * and it just becomes fruit juice... whereas see invisible
  299.          * tastes like "enchanted" fruit juice, it similarly cancels.
  300.          */
  301.     obj->blessed = obj->cursed = FALSE;
  302. }
  303.  
  304. static int
  305. bhitgold(gold, otmp)
  306. register struct gold *gold;
  307. register struct obj *otmp;
  308. {
  309.     switch(otmp->otyp) {
  310.     case WAN_TELEPORTATION:
  311. #ifdef SPELLS
  312.     case SPE_TELEPORT_AWAY:
  313. #endif
  314.         rlocgold(gold);
  315.         break;
  316.     }
  317.     return 1;
  318. }
  319.  
  320. STATIC_PTR
  321. int
  322. bhito(obj, otmp)    /* object obj was hit by the effect of wand otmp */
  323. register struct obj *obj, *otmp;    /* returns TRUE if sth was done */
  324. {
  325.     register int res = 1;
  326.     struct obj *otmp2;
  327.  
  328.     if(obj == uball || obj == uchain)
  329.         res = 0;
  330.     else
  331.     switch(otmp->otyp) {
  332.     case WAN_POLYMORPH:
  333. #ifdef SPELLS
  334.     case SPE_POLYMORPH:
  335. #endif
  336.         /* avoid unicorn/tool abuse */
  337.         if (obj->otyp == UNICORN_HORN) obj->olet = WEAPON_SYM;
  338.  
  339.         /* preserve symbol and quantity */
  340.         otmp2 = mkobj_at(obj->olet, obj->ox, obj->oy, FALSE);
  341.         otmp2->quan = obj->quan;
  342. #ifdef MAIL
  343.         /* You can't send yourself 100 mail messages and then
  344.          * polymorph them into useful scrolls
  345.          */
  346.         if (obj->otyp == SCR_MAIL) {
  347.             otmp2->otyp = SCR_MAIL;
  348.             otmp2->spe = 1;
  349.         }
  350. #endif
  351.         /* keep special fields (including charges on wands) */
  352.         if (index(charged_objs, otmp2->olet)) otmp2->spe = obj->spe;
  353.  
  354.         /* Amulet gets cheap   stewr 870807 */
  355.         if (obj->otyp == AMULET_OF_YENDOR) otmp2->spe = -1;
  356.  
  357.         otmp2->cursed = obj->cursed;
  358.         otmp2->blessed = obj->blessed;
  359.         otmp2->rustfree = obj->rustfree;
  360.  
  361.         /* Keep chest/box traps and poisoned ammo if we may */
  362.         if (obj->otrapped && Is_box(otmp2))
  363.             otmp2->otrapped = 1;
  364.         if (obj->opoisoned && 
  365.             (otmp2->olet == WEAPON_SYM && otmp2->otyp <= SHURIKEN))
  366.             otmp2->opoisoned = 1;
  367.  
  368.         if (obj->otyp == CORPSE){
  369.             /* Turn dragon corpses into dragon armors */
  370.             if (obj->corpsenm >= PM_GRAY_DRAGON
  371.                 && obj->corpsenm <= PM_YELLOW_DRAGON) {
  372.             if (!rn2(10)) { /* Random failure */
  373.                 otmp2->otyp = TIN;
  374.                 otmp2->known = otmp2->dknown = 1;
  375.             } else {
  376.                 otmp2->otyp = DRAGON_SCALE_MAIL;
  377.                 otmp2->olet = ARMOR_SYM;
  378.                 otmp2->spe = 0;
  379.                 otmp2->rustfree = 1;
  380.                 otmp2->quan = 1;
  381.                 otmp2->cursed = 0;
  382.             }
  383.             otmp2->corpsenm = obj->corpsenm;
  384.             /* and croc corpses into shoes */
  385.             } else if (obj->corpsenm == PM_CROCODILE) {
  386.             otmp2->otyp = LOW_BOOTS;
  387.             otmp2->olet = ARMOR_SYM;
  388.             otmp2->spe = 0;
  389.             otmp2->rustfree = 1;
  390.             otmp2->quan = 1;
  391.             otmp2->cursed = 0;
  392.             }
  393.         }
  394.  
  395.         /* no box contents --KAA */
  396.         if (Is_container(otmp2)) delete_contents(otmp2);
  397.  
  398.         if(otmp2->otyp == MAGIC_LAMP) otmp2->otyp = LAMP;
  399.  
  400.         if(otmp2->otyp == WAN_WISHING)
  401.             while(otmp2->otyp == WAN_WISHING ||
  402.                   otmp2->otyp == WAN_POLYMORPH)
  403.                 otmp2->otyp = rnd_class(WAN_LIGHT, WAN_LIGHTNING);
  404.  
  405.         /* update the weight */
  406.         otmp2->owt = weight(otmp2);
  407.         delobj(obj);
  408.         break;
  409.     case WAN_STRIKING:
  410. #ifdef SPELLS
  411.     case SPE_FORCE_BOLT:
  412. #endif
  413.         if(obj->otyp == BOULDER)
  414.             fracture_rock(obj);
  415.         else if(obj->otyp == STATUE)
  416.             (void) break_statue(obj);
  417.         else
  418.             res = 0;
  419.         break;
  420.     case WAN_CANCELLATION:
  421. #ifdef SPELLS
  422.     case SPE_CANCELLATION:
  423. #endif
  424.         cancel_item(obj);
  425.         break;
  426.     case WAN_TELEPORTATION:
  427. #ifdef SPELLS
  428.     case SPE_TELEPORT_AWAY:
  429. #endif
  430.         rloco(obj);
  431.         break;
  432.     case WAN_MAKE_INVISIBLE:
  433.         obj->oinvis = 1;
  434.         break;
  435.     case WAN_UNDEAD_TURNING:
  436. #ifdef SPELLS
  437.     case SPE_TURN_UNDEAD:
  438. #endif
  439.         res = !!revive(obj,FALSE);
  440.         break;
  441.     case WAN_OPENING:
  442.     case WAN_LOCKING:
  443. #ifdef SPELLS
  444.     case SPE_KNOCK:
  445.     case SPE_WIZARD_LOCK:
  446. #endif
  447.         if(Is_box(obj))
  448.             res = boxlock(obj, otmp);
  449.         else
  450.             res = 0;
  451.         if (res /* && obj->olet == WAND_SYM */)
  452.             makeknown(obj->otyp);
  453.         break;
  454.     case WAN_SLOW_MONSTER:        /* no effect on objects */
  455. #ifdef SPELLS
  456.     case SPE_SLOW_MONSTER:
  457. #endif
  458.     case WAN_SPEED_MONSTER:
  459.     case WAN_NOTHING:
  460. #ifdef PROBING
  461.     case WAN_PROBING:
  462. #endif
  463.         res = 0;
  464.         break;
  465.     default:
  466.         impossible("What an interesting effect (%u)", otmp->otyp);
  467.     }
  468.     return(res);
  469. }
  470.  
  471. /*
  472.  * zappable - returns 1 if zap is available, 0 otherwise.
  473.  *          it removes a charge from the wand if zappable.
  474.  * added by GAN 11/03/86
  475.  */
  476. int
  477. zappable(wand)
  478. register struct obj *wand;
  479. {
  480.     if(wand->spe < 0 || (wand->spe == 0 && rn2(121)))
  481.         return 0;
  482.     if(wand->spe == 0)
  483.         You("wrest one more spell from the worn-out wand.");
  484.     wand->spe--;
  485.     return 1;
  486. }
  487.  
  488. /*
  489.  * zapnodir - zaps an NODIR wand.
  490.  * added by GAN 11/03/86
  491.  */
  492. void
  493. zapnodir(wand)
  494. register struct obj *wand;
  495. {
  496.     switch(wand->otyp){
  497.         case WAN_LIGHT:
  498.             litroom(TRUE);
  499.             break;
  500.         case WAN_SECRET_DOOR_DETECTION:
  501.             if(!findit()) return;
  502.             break;
  503.         case WAN_CREATE_MONSTER:
  504.             { register int cnt = 1;
  505.             if(!rn2(23)) cnt += rn2(7) + 1;
  506.             while(cnt--)
  507.                 (void) makemon((struct permonst *) 0, u.ux, u.uy);
  508.             }
  509.             break;
  510.         case WAN_WISHING:
  511.             if(Luck + rn2(5) < 0) {
  512.                 pline("Unfortunately, nothing happens.");
  513.                 break;
  514.             }
  515.             makewish();
  516.             break;
  517.     }
  518.     if(!objects[wand->otyp].oc_name_known) {
  519.             makeknown(wand->otyp);
  520.             more_experienced(0,10);
  521.     }
  522. }
  523.  
  524. static void
  525. backfire(otmp)
  526.  
  527.     register struct obj * otmp;
  528. {
  529.     pline("The %s suddenly explodes!", xname(otmp));
  530.     losehp(d(otmp->spe+2,6), "exploding wand", KILLED_BY_AN);
  531.     useup(otmp);
  532. }
  533.  
  534. static const char NEARDATA zap_syms[] = { WAND_SYM, 0 };
  535.  
  536. int
  537. dozap()
  538. {
  539.     register struct obj *obj;
  540.     int    damage;
  541.  
  542.     obj = getobj(zap_syms, "zap");
  543.     if(!obj) return(0);
  544.  
  545.     check_unpaid(obj);
  546.  
  547.     /* zappable addition done by GAN 11/03/86 */
  548.     if(!zappable(obj)) pline(nothing_happens);
  549.     else if(obj->cursed && !rn2(100)) {
  550.         backfire(obj);    /* the wand blows up in your face! */
  551.         return(1);
  552.     } else if(!(objects[obj->otyp].bits & NODIR) && !getdir(1)) {
  553.         if (!Blind)
  554.             pline("The %s glows and fades.", xname(obj));
  555.         /* make him pay for knowing !NODIR */
  556.     } else if(!u.dx && !u.dy && !u.dz && !(objects[obj->otyp].bits & NODIR)) {
  557.         if((damage = zapyourself(obj)))
  558.         losehp(damage, self_pronoun("zapped %sself with a wand", "him"),
  559.             NO_KILLER_PREFIX);
  560.     }
  561.     else {
  562.         weffects(obj);
  563. #if defined(ALTARS) && defined(THEOLOGY)
  564.         if(priesthit) ghod_hitsu();
  565.         priesthit = FALSE;
  566. #endif
  567.     }
  568.     if (obj->spe < 0) {
  569.         pline ("The %s %sturns to dust.",
  570.            xname(obj), Blind ? "" : "glows violently, then ");
  571.         useup(obj);
  572.     }
  573.     return(1);
  574. }
  575.  
  576. int
  577. zapyourself(obj)
  578.     register struct obj    *obj;
  579. {
  580.     struct obj    *otmp;
  581.     int    damage = 0;
  582.  
  583.     switch(obj->otyp) {
  584.         case WAN_STRIKING:
  585. #ifdef SPELLS
  586.         case SPE_FORCE_BOLT:
  587. #endif
  588.             if(Antimagic) {
  589.             shieldeff(u.ux, u.uy);
  590.             pline("Boing!");
  591.             } else {
  592.             You("magically bash yourself!");
  593.             damage=d(8,6);
  594.             }
  595.             break;
  596.         case WAN_LIGHTNING:
  597.             makeknown(WAN_LIGHTNING);
  598.             if (!Shock_resistance) {
  599.             pline("Idiot!  You've shocked yourself!");
  600.             damage = d(12,6);
  601.             } else {
  602.             shieldeff(u.ux, u.uy);
  603.             You("zap yourself, but seem unharmed.");
  604. #ifdef POLYSELF
  605. #ifdef GOLEMS
  606.             ugolemeffects(AD_ELEC, d(12,6));
  607. #endif /* GOLEMS */
  608. #endif
  609.             }
  610.             destroy_item(WAND_SYM, AD_ELEC);
  611.             destroy_item(RING_SYM, AD_ELEC);
  612.             if(!Blind) {
  613.                 You("are blinded by the flash!");
  614.                 make_blinded((long)rnd(100),FALSE);
  615.             }
  616.             break;
  617.         case WAN_FIRE:
  618.             makeknown(WAN_FIRE);
  619. #ifdef SPELLS
  620.         case SPE_FIREBALL:
  621. #endif
  622. #ifdef MUSIC
  623.         case FIRE_HORN:
  624. #endif
  625.             pline("You've set light to yourself!");
  626.             if (Fire_resistance) {
  627.             shieldeff(u.ux, u.uy);
  628.             You("feel mildly hot.");
  629. #ifdef POLYSELF
  630. #ifdef GOLEMS
  631.             ugolemeffects(AD_FIRE, d(12,6));
  632. #endif /* GOLEMS */
  633. #endif
  634.             } else
  635.             damage = d(12,6);
  636.             destroy_item(SCROLL_SYM, AD_FIRE);
  637.             destroy_item(POTION_SYM, AD_FIRE);
  638. #ifdef SPELLS
  639.             destroy_item(SPBOOK_SYM, AD_FIRE);
  640. #endif
  641.             break;
  642.         case WAN_COLD:
  643.             makeknown(WAN_COLD);
  644. #ifdef SPELLS
  645.         case SPE_CONE_OF_COLD:
  646. #endif
  647. #ifdef MUSIC
  648.         case FROST_HORN:
  649. #endif
  650.             if (Cold_resistance) {
  651.             shieldeff(u.ux, u.uy);
  652.             You("feel mildly chilly.");
  653. #ifdef POLYSELF
  654. #ifdef GOLEMS
  655.             ugolemeffects(AD_COLD, d(12,6));
  656. #endif /* GOLEMS */
  657. #endif
  658.             } else {
  659.             You("imitate a popsicle!");
  660.             damage = d(12,6);
  661.             }
  662.             destroy_item(POTION_SYM, AD_COLD);
  663.             break;
  664.         case WAN_MAGIC_MISSILE:
  665.             makeknown(WAN_MAGIC_MISSILE);
  666. #ifdef SPELLS
  667.         case SPE_MAGIC_MISSILE:
  668. #endif
  669.             if(Antimagic) {
  670.             shieldeff(u.ux, u.uy);
  671.             pline("The missiles bounce!");
  672.             } else {
  673.             damage = d(4,6);
  674.             pline("Idiot!  You've shot yourself!");
  675.             }
  676.             break;
  677.         case WAN_POLYMORPH:
  678. #ifdef POLYSELF
  679.             makeknown(WAN_POLYMORPH);
  680. #endif
  681. #ifdef SPELLS
  682.         case SPE_POLYMORPH:
  683. #endif
  684. #ifdef POLYSELF
  685.             polyself();
  686. #else
  687.             newman();
  688. #endif
  689.             break;
  690.         case WAN_CANCELLATION:
  691. #ifdef SPELLS
  692.         case SPE_CANCELLATION:
  693. #endif
  694. #ifdef POLYSELF
  695. #ifdef GOLEMS
  696.             if (u.umonnum == PM_CLAY_GOLEM) {
  697.             if (!Blind)
  698.                 pline("Some writing vanishes from your head!");
  699.             rehumanize();
  700.             break;
  701.             }
  702. #endif /* GOLEMS */
  703. #endif
  704.             for(otmp = invent; otmp; otmp = otmp->nobj)
  705.             cancel_item(otmp);
  706. #ifdef POLYSELF
  707.             if(u.mtimedone) rehumanize();
  708. #endif
  709.             flags.botl = 1;  /* because of potential AC change */
  710.             find_ac();
  711.             break;
  712.            case WAN_MAKE_INVISIBLE:
  713.             if (!Invis && !See_invisible)
  714.             makeknown(WAN_MAKE_INVISIBLE);
  715.             HInvis |= INTRINSIC;
  716.             if (!See_invisible) newsym(u.ux, u.uy);
  717.             break;
  718.            case WAN_SPEED_MONSTER:
  719.             if (!(Fast & INTRINSIC)) {
  720.             Fast |= INTRINSIC;
  721.             You("seem to be moving faster.");
  722.             makeknown(WAN_SPEED_MONSTER);
  723.             }
  724.             break;
  725.            case WAN_SLEEP:
  726.             makeknown(WAN_SLEEP);
  727. #ifdef SPELLS
  728.         case SPE_SLEEP:
  729. #endif
  730.             if(Sleep_resistance) {
  731.             shieldeff(u.ux, u.uy);
  732.             You("don't feel sleepy!");
  733.             } else {
  734.             pline("The sleep ray hits you!");
  735.             nomul(-rn2(50));
  736.             }
  737.             break;
  738.         case WAN_SLOW_MONSTER:
  739. #ifdef SPELLS
  740.         case SPE_SLOW_MONSTER:
  741. #endif
  742.             if(Fast & (TIMEOUT | INTRINSIC)) {
  743.             Fast &= ~(TIMEOUT | INTRINSIC);
  744.             You("seem to be moving slower.");
  745.             }
  746.             break;
  747.         case WAN_TELEPORTATION:
  748. #ifdef SPELLS
  749.         case SPE_TELEPORT_AWAY:
  750. #endif
  751.             tele();
  752.             break;
  753.         case WAN_DEATH:
  754. #ifdef SPELLS
  755.         case SPE_FINGER_OF_DEATH:
  756. #endif
  757. #ifdef POLYSELF
  758.             if (is_undead(uasmon)) {
  759.             pline((obj->otyp == WAN_DEATH) ?
  760.               "The wand shoots an apparently harmless beam at you."
  761.               : "You seem no deader than before.");
  762.             break;
  763.             }
  764. #endif
  765.             killer_format = NO_KILLER_PREFIX;
  766.             killer = self_pronoun("shot %sself with a death ray","him");
  767.             You("irradiate yourself with pure energy!");
  768.             You("die.");
  769.             makeknown(WAN_DEATH);
  770.             /* They might survive with an amulet of life saving */
  771.             done(DIED);
  772.             break;
  773. #ifdef SPELLS
  774.         case SPE_TURN_UNDEAD:
  775. #endif
  776.         case WAN_UNDEAD_TURNING:
  777. #ifdef POLYSELF
  778.             if (is_undead(uasmon)) {
  779.             You("feel frightened and %sstunned.",
  780.                  Stunned ? "even more " : "");
  781.             make_stunned(HStun + rnd(30), FALSE);
  782.             }
  783. #endif
  784.             break;
  785. #ifdef SPELLS
  786.         case SPE_DIG:
  787.         case SPE_DETECT_UNSEEN:
  788. #endif
  789.         case WAN_DIGGING:
  790.         case WAN_NOTHING:
  791.         case WAN_OPENING:
  792.         case WAN_LOCKING:
  793. #ifdef SPELLS
  794.         case SPE_KNOCK:
  795.         case SPE_WIZARD_LOCK:
  796. #endif
  797.             break;
  798. #ifdef PROBING
  799.         case WAN_PROBING:
  800.             makeknown(WAN_PROBING);
  801.             ustatusline();
  802.             break;
  803. #endif
  804.         default: impossible("object %d used?",obj->otyp);
  805.     }
  806.     return(damage);
  807. }
  808.  
  809. /* called for various wand and spell effects - M. Stephenson */
  810. void
  811. weffects(obj)
  812. register struct    obj    *obj;
  813. {
  814.     xchar zx,zy;
  815.  
  816.     if(objects[obj->otyp].bits & IMMEDIATE) {
  817.         if(u.uswallow)    (void)bhitm(u.ustuck, obj);
  818.         else if(u.dz) {
  819.         if(u.dz > 0) {
  820. #ifdef STRONGHOLD
  821.             if(levl[u.ux][u.uy].typ == DRAWBRIDGE_DOWN &&
  822.                (obj->otyp == WAN_LOCKING
  823. # ifdef SPELLS
  824.             || obj->otyp == SPE_WIZARD_LOCK
  825. # endif
  826.             ))
  827.                 (void)close_drawbridge(u.ux, u.uy);
  828.             else
  829. #endif
  830.             {
  831.             register struct obj *otmp, *otmp2 = (struct obj *)0;
  832.  
  833.             if(levl[u.ux][u.uy].gmask)
  834.                 (void) bhitgold(g_at(u.ux, u.uy), obj);
  835.             /* pre-reverse the polymorph pile,  -dave- 3/90 */
  836.             if (obj->otyp == WAN_POLYMORPH
  837. #ifdef SPELLS
  838.                 || obj->otyp == SPE_POLYMORPH
  839. #endif
  840.                                 ) {
  841.                 otmp = level.objects[u.ux][u.uy];
  842.                 level.objects[u.ux][u.uy] = otmp2;
  843.                 while(otmp) {
  844.                     otmp2 = otmp->nexthere;
  845.                     otmp->nexthere = level.objects[u.ux][u.uy];
  846.                     level.objects[u.ux][u.uy] = otmp;
  847.                     otmp = otmp2;
  848.                 }
  849.             }
  850.             for(otmp = level.objects[u.ux][u.uy];
  851.                             otmp; otmp = otmp2) {
  852.                 /* changed by GAN to hit all objects there */
  853.                 otmp2 = otmp->nexthere;
  854.                 /* save pointer as bhito may destroy otmp */
  855.                 (void) bhito(otmp, obj);
  856.             }
  857.             }
  858.         }
  859.         } else (void) bhit(u.dx,u.dy,rn1(8,6),0,bhitm,bhito,obj);
  860.     } else {
  861.         switch(obj->otyp){
  862.         case WAN_LIGHT:
  863. #ifdef SPELLS
  864.         case SPE_LIGHT:
  865. #endif
  866.             litroom(TRUE);
  867.             break;
  868.         case WAN_SECRET_DOOR_DETECTION:
  869. #ifdef SPELLS
  870.         case SPE_DETECT_UNSEEN:
  871. #endif
  872.             if(!findit()) return;
  873.             break;
  874.         case WAN_CREATE_MONSTER:
  875.             { register int cnt = 1;
  876.             if(!rn2(23)) cnt += rn2(7) + 1;
  877.             while(cnt--)
  878.                 (void) makemon((struct permonst *) 0, u.ux, u.uy);
  879.             }
  880.             break;
  881.         case WAN_WISHING:
  882.             if(Luck + rn2(5) < 0) {
  883.                 pline("Unfortunately, nothing happens.");
  884.                 break;
  885.             }
  886.             makewish();
  887.             break;
  888.         case WAN_DIGGING:
  889. #ifdef SPELLS
  890.         case SPE_DIG:
  891. #endif
  892.             /* Original effect (approximately):
  893.              * from CORR: dig until we pierce a wall
  894.              * from ROOM: piece wall and dig until we reach
  895.              * an ACCESSIBLE place.
  896.              * Currently: dig for digdepth positions;
  897.              * also down on request of Lennart Augustsson.
  898.              */
  899.             { register struct rm *room;
  900.               register int digdepth,dlx,dly;
  901.               register boolean shopdoor = FALSE;
  902. #ifdef __GNULINT__
  903.             dlx = dly = 0;
  904. #endif
  905.             if(u.uswallow) {
  906.                 register struct monst *mtmp = u.ustuck;
  907.  
  908.                 if (!is_whirly(mtmp->data)) {
  909.                     if (is_animal(mtmp->data)) 
  910.                         if (Blind) 
  911.                         You("pierce its stomach wall!");
  912.                         else 
  913.                         You("pierce %s's stomach wall!",
  914.                                mon_nam(mtmp));
  915.                     mtmp->mhp = 1;    /* almost dead */
  916.                     expels(mtmp, mtmp->data,
  917.                            !is_animal(mtmp->data));
  918.                 }
  919.                 break;
  920.             }
  921.             if(u.dz) {
  922.                 if(u.dz < 0) {
  923.                 You("loosen a rock from the ceiling.");
  924.                 pline("It falls on your %s!",
  925.                     body_part(HEAD));
  926.                 losehp(1, "falling rock", KILLED_BY_AN);
  927.                 (void) mksobj_at((int)ROCK, u.ux, u.uy);
  928.                 fobj->quan = 1;
  929.                 stackobj(fobj);
  930.                 if(Invisible) newsym(u.ux, u.uy);
  931.                 } else {
  932. #ifdef MACOS
  933.                 segments |= SEG_ZAP;
  934. #endif
  935.                 dighole();
  936.                 }
  937.                 break;
  938.             }
  939.             zx = u.ux+u.dx;
  940.             zy = u.uy+u.dy;
  941.             digdepth = 8 + rn2(18);
  942.             Tmp_at2(-1, '*');    /* open call */
  943.             while(--digdepth >= 0) {
  944.                 if(!isok(zx,zy)) break;
  945.                 room = &levl[zx][zy];
  946.                 Tmp_at2(zx,zy);
  947.                 if(is_maze_lev) {
  948.                 if(IS_WALL(room->typ)) {
  949.                     if(room->diggable == W_DIGGABLE)
  950.                     room->typ = ROOM;
  951.                     else if(!Blind)
  952.                     pline("The wall glows then fades.");
  953.                     break;
  954.                 }
  955.                 if(room->typ == STONE) {
  956.                     if(room->diggable == W_DIGGABLE)
  957.                     room->typ = CORR;
  958.                     else if (!Blind)
  959.                     pline("The rock glows then fades.");
  960.                     break;
  961.                 }
  962.                 } else
  963.                 if(IS_ROCK(room->typ))
  964.                     if(may_dig(zx,zy))
  965.                     if(IS_WALL(room->typ) ||
  966.                         room->typ == SDOOR) {
  967.                         room->typ = DOOR;
  968.                         room->doormask = D_NODOOR;
  969.                         mnewsym(zx, zy);
  970.                         if (cansee(zx,zy)) prl(zx, zy);
  971.                         digdepth -= 2;
  972.                     } else {
  973.                         room->typ = CORR;
  974.                         digdepth--;
  975.                     }
  976.                     else
  977.                     break;
  978.                 else if(closed_door(zx, zy)) {
  979.                     room->doormask = D_NODOOR;
  980.                     mnewsym(zx, zy);
  981.                     if (cansee(zx,zy)) prl(zx, zy);
  982.                     if(in_shop(zx,zy)) {
  983.                     shopdoor = TRUE;
  984.                     dlx = zx;
  985.                     dly = zy;
  986.                     }
  987.                     digdepth -= 2;
  988.                 }
  989.                 mnewsym(zx,zy);
  990.                 zx += u.dx;
  991.                 zy += u.dy;
  992.             }
  993.             mnewsym(zx,zy);    /* not always necessary */
  994.             Tmp_at2(-1,-1);    /* closing call */
  995.             if(!Blind) prl(u.ux+u.dx, u.uy+u.dy);
  996.             if(shopdoor)
  997.                 pay_for_door(dlx, dly, "destroy");
  998.             break;
  999.             }
  1000.         default:
  1001. #ifdef SPELLS
  1002.             if((int) obj->otyp >= SPE_MAGIC_MISSILE) {
  1003.  
  1004.                 buzz((int) obj->otyp - SPE_MAGIC_MISSILE + 10,
  1005.                  (int)u.ulevel / 2 + 1, u.ux, u.uy, u.dx, u.dy);
  1006.             } else
  1007. #endif
  1008.  
  1009.                 buzz((int) obj->otyp - WAN_MAGIC_MISSILE, 6,
  1010.                  u.ux, u.uy, u.dx, u.dy);
  1011.             break;
  1012.         }
  1013.         if(!objects[obj->otyp].oc_name_known) {
  1014.             makeknown(obj->otyp);
  1015.             more_experienced(0,10);
  1016.         }
  1017.     }
  1018.     return;
  1019. }
  1020.  
  1021. const char *
  1022. exclam(force)
  1023. register int force;
  1024. {
  1025.     /* force == 0 occurs e.g. with sleep ray */
  1026.     /* note that large force is usual with wands so that !! would
  1027.         require information about hand/weapon/wand */
  1028.     return (const char *)((force < 0) ? "?" : (force <= 4) ? "." : "!");
  1029. }
  1030.  
  1031. void
  1032. hit(str,mtmp,force)
  1033. register const char *str;
  1034. register struct monst *mtmp;
  1035. register const char *force;        /* usually either "." or "!" */
  1036. {
  1037.     if(!cansee(mtmp->mx,mtmp->my) || !flags.verbose) pline("The %s hits it.", str);
  1038.     else pline("The %s hits %s%s", str, mon_nam(mtmp), force);
  1039. }
  1040.  
  1041. void
  1042. miss(str,mtmp)
  1043. register const char *str;
  1044. register struct monst *mtmp;
  1045. {
  1046.     pline("The %s misses %s.", str,
  1047.           (cansee(mtmp->mx,mtmp->my) && flags.verbose) ? mon_nam(mtmp) : "it");
  1048. }
  1049.  
  1050. /* bhit: called when a weapon is thrown (sym = obj->olet) or when an
  1051.    IMMEDIATE wand is zapped (sym = 0); the weapon falls down at end of
  1052.    range or when a monster is hit; the monster is returned, and bhitpos
  1053.    is set to the final position of the weapon thrown; the ray of a wand
  1054.    may affect several objects and monsters on its path - for each of
  1055.    these an argument function is called. */
  1056. /* check !u.uswallow before calling bhit() */
  1057.  
  1058. struct monst *
  1059. bhit(ddx,ddy,range,sym,fhitm,fhito,obj)
  1060. register int ddx,ddy,range;        /* direction and range */
  1061. char sym;                /* symbol displayed on path */
  1062. int FDECL((*fhitm), (struct monst *, struct obj *)),
  1063.     FDECL((*fhito), (struct obj *, struct obj *));        /* fns called when mon/obj hit */
  1064. struct obj *obj;            /* 2nd arg to fhitm/fhito */
  1065. {
  1066.     register struct monst *mtmp;
  1067.     register struct obj *otmp;
  1068.     register uchar typ;
  1069.     boolean shopdoor = FALSE;
  1070. #ifdef __GNULINT__
  1071.     xchar dlx=0, dly=0;
  1072. #else
  1073.     xchar dlx, dly;
  1074. #endif
  1075.  
  1076.     bhitpos.x = u.ux;
  1077.     bhitpos.y = u.uy;
  1078.  
  1079.     if(sym) {
  1080.         tmp_at(-1, sym);    /* open call */
  1081. #ifdef TEXTCOLOR
  1082.         tmp_at(-3, (int)objects[obj->otyp].oc_color);
  1083. #else
  1084.         tmp_at(-3, (int)AT_OBJ);
  1085. #endif
  1086.     }
  1087.     while(range-- > 0) {
  1088. #ifdef STRONGHOLD
  1089.         int x,y;
  1090. #endif
  1091.         bhitpos.x += ddx;
  1092.         bhitpos.y += ddy;
  1093. #ifdef STRONGHOLD
  1094.         x = bhitpos.x; y = bhitpos.y;
  1095.         if (find_drawbridge(&x,&y) && !sym)
  1096.             switch (obj->otyp) {
  1097.             case WAN_OPENING:
  1098. # ifdef SPELLS
  1099.             case SPE_KNOCK:
  1100. # endif
  1101.                 if (is_db_wall(bhitpos.x, bhitpos.y))
  1102.                 (void) open_drawbridge(x,y);
  1103.                 break;
  1104.             case WAN_LOCKING:
  1105. # ifdef SPELLS
  1106.             case SPE_WIZARD_LOCK:
  1107. # endif
  1108.                 (void) close_drawbridge(x,y);
  1109.                 break;
  1110.             case WAN_STRIKING:
  1111. # ifdef SPELLS
  1112.             case SPE_FORCE_BOLT:
  1113. # endif
  1114.                 if (levl[bhitpos.x][bhitpos.y].typ != 
  1115.                    DRAWBRIDGE_UP)
  1116.                     destroy_drawbridge(x,y);
  1117.             }
  1118. #endif /* STRONGHOLD /**/
  1119.         if(MON_AT(bhitpos.x, bhitpos.y)){
  1120.             mtmp = m_at(bhitpos.x,bhitpos.y);
  1121.             if(sym) {
  1122.                 tmp_at(-1, -1);    /* close call */
  1123.                 return(mtmp);
  1124.             }
  1125.             (*fhitm)(mtmp, obj);
  1126.             range -= 3;
  1127.         }
  1128.         /* modified by GAN to hit all objects */
  1129.         if(fhito){
  1130.             int hitanything = 0;
  1131.             register struct obj *next_obj = (struct obj *)0;
  1132.  
  1133.             if((fhito == bhito) && levl[bhitpos.x][bhitpos.y].gmask)
  1134.             hitanything += bhitgold(g_at(bhitpos.x,bhitpos.y),obj);
  1135.             /* pre-reverse the polymorph pile,  -dave- 3/90 */
  1136.             if (obj->otyp == WAN_POLYMORPH
  1137. #ifdef SPELLS
  1138.                 || obj->otyp == SPE_POLYMORPH
  1139. #endif
  1140.                             ) {
  1141.             otmp = level.objects[bhitpos.x][bhitpos.y];
  1142.             level.objects[bhitpos.x][bhitpos.y] = next_obj;
  1143.             while(otmp) {
  1144.                 next_obj = otmp->nexthere;
  1145.                 otmp->nexthere = level.objects[bhitpos.x][bhitpos.y];
  1146.                 level.objects[bhitpos.x][bhitpos.y] = otmp;
  1147.                 otmp = next_obj; 
  1148.             }
  1149.             }
  1150.             for(otmp = level.objects[bhitpos.x][bhitpos.y];
  1151.                             otmp; otmp = next_obj) {
  1152.             /* Fix for polymorph bug, Tim Wright */
  1153.             next_obj = otmp->nexthere;
  1154.             hitanything += (*fhito)(otmp, obj);
  1155.             }
  1156.             if(hitanything)    range--;
  1157.         }
  1158.         typ = levl[bhitpos.x][bhitpos.y].typ;
  1159.         if((IS_DOOR(typ) || typ == SDOOR) && !sym) {
  1160.             switch (obj->otyp) {
  1161.             case WAN_OPENING:
  1162.             case WAN_LOCKING:
  1163.             case WAN_STRIKING:
  1164. #ifdef SPELLS
  1165.             case SPE_KNOCK:
  1166.             case SPE_WIZARD_LOCK:
  1167.             case SPE_FORCE_BOLT:
  1168. #endif
  1169.                 if (doorlock(obj, bhitpos.x, bhitpos.y)) {
  1170.                 makeknown(obj->otyp);
  1171.                 if (levl[bhitpos.x][bhitpos.y].doormask == D_BROKEN
  1172.                     && in_shop(bhitpos.x, bhitpos.y)) {
  1173.                     shopdoor = TRUE;
  1174.                     dlx = bhitpos.x; dly = bhitpos.y;
  1175.                 }
  1176.                 }
  1177.                 break;
  1178.             }
  1179.         }
  1180.         if(!ZAP_POS(typ) || closed_door(bhitpos.x, bhitpos.y)) {
  1181.             bhitpos.x -= ddx;
  1182.             bhitpos.y -= ddy;
  1183.             break;
  1184.         }
  1185.         if(sym) tmp_at(bhitpos.x, bhitpos.y);
  1186. #ifdef SINKS
  1187.         if(sym && IS_SINK(typ))
  1188.             break;    /* physical objects fall onto sink */
  1189. #endif
  1190.     }
  1191.  
  1192.     /* leave last symbol unless in a pool */
  1193.     if(sym)
  1194.        tmp_at(-1, is_pool(bhitpos.x,bhitpos.y) ? -1 : 0);
  1195.  
  1196.     if(shopdoor)
  1197.         pay_for_door(dlx, dly, "destroy");
  1198.  
  1199.     return (struct monst *)0;
  1200. }
  1201.  
  1202. struct monst *
  1203. boomhit(dx, dy)
  1204. int dx, dy;
  1205. {
  1206.     register int i, ct;
  1207.     char sym = ')';
  1208.  
  1209.     bhitpos.x = u.ux;
  1210.     bhitpos.y = u.uy;
  1211.  
  1212.     for(i=0; i<8; i++) if(xdir[i] == dx && ydir[i] == dy) break;
  1213.     tmp_at(-1, sym);    /* open call */
  1214. #ifndef TEXTCOLOR
  1215.     tmp_at(-3, (int)AT_OBJ);
  1216. #else
  1217.     tmp_at(-3, HI_METAL);
  1218. #endif
  1219.     for(ct=0; ct<10; ct++) {
  1220.         if(i == 8) i = 0;
  1221.         sym = ')' + '(' - sym;
  1222.         tmp_at(-2, sym);    /* change let call */
  1223.         dx = xdir[i];
  1224.         dy = ydir[i];
  1225.         bhitpos.x += dx;
  1226.         bhitpos.y += dy;
  1227.         if(MON_AT(bhitpos.x, bhitpos.y)){
  1228.             tmp_at(-1,-1);
  1229.             return(m_at(bhitpos.x,bhitpos.y));
  1230.         }
  1231.         if(!ZAP_POS(levl[bhitpos.x][bhitpos.y].typ)) {
  1232.             bhitpos.x -= dx;
  1233.             bhitpos.y -= dy;
  1234.             break;
  1235.         }
  1236.         if(bhitpos.x == u.ux && bhitpos.y == u.uy) { /* ct == 9 */
  1237.             if(Fumbling || rn2(20) >= ACURR(A_DEX)){
  1238.                 /* we hit ourselves */
  1239.                 (void) thitu(10, rnd(10), (struct obj *)0,
  1240.                     "boomerang");
  1241.                 break;
  1242.             } else {    /* we catch it */
  1243.                 tmp_at(-1,-1);
  1244.                 pline("Skillfully, you catch the boomerang.");
  1245.                 return(&youmonst);
  1246.             }
  1247.         }
  1248.         tmp_at(bhitpos.x, bhitpos.y);
  1249.         if(ct % 5 != 0) i++;
  1250. #ifdef SINKS
  1251.         if(IS_SINK(levl[bhitpos.x][bhitpos.y].typ))
  1252.             break;    /* boomerang falls on sink */
  1253. #endif
  1254.     }
  1255.     tmp_at(-1, -1);    /* do not leave last symbol */
  1256.     return (struct monst *)0;
  1257. }
  1258.  
  1259. static uchar
  1260. dirlet(dx, dy)
  1261. register int dx, dy;
  1262. {
  1263.     return
  1264.         (dx == dy) ? LSLANT_SYM :
  1265.         (dx && dy) ? RSLANT_SYM :
  1266.         dx ? HBEAM_SYM : VBEAM_SYM;
  1267. }
  1268.  
  1269. static int
  1270. zhit(mon, type, nd)            /* returns damage to mon */
  1271. register struct monst *mon;
  1272. register int type, nd;
  1273. {
  1274.     register int tmp = 0;
  1275.     register int abstype = abs(type) % 10;
  1276.  
  1277.     switch(abstype) {
  1278.     case 0:            /* magic missile */
  1279.         tmp = d(nd,6);
  1280.         break;
  1281.     case 1:            /* fire */
  1282.         if(resists_fire(mon->data)) {
  1283.             shieldeff(mon->mx, mon->my);
  1284.             break;
  1285.         }
  1286.         tmp = d(nd,6);
  1287.         if(resists_cold(mon->data)) tmp += 7;
  1288.         break;
  1289.     case 2:            /* sleep */
  1290.         tmp = 0;
  1291.         if(resists_sleep(mon->data) ||
  1292.            resist(mon, (type == 2) ? WAND_SYM : '\0', 0, NOTELL))
  1293.             shieldeff(mon->mx, mon->my);
  1294.         else if (mon->mcanmove) {
  1295.             int tmp2 = d(nd,25);
  1296.             mon->mcanmove = 0;
  1297.             if (mon->mfrozen + tmp2 > 127) mon->mfrozen = 127;
  1298.             else mon->mfrozen += tmp2;
  1299.         }
  1300.         break;
  1301.     case 3:            /* cold */
  1302.         if(resists_cold(mon->data)) {
  1303.             shieldeff(mon->mx, mon->my);
  1304.             break;
  1305.         }
  1306.         tmp = d(nd,6);
  1307.         if(resists_fire(mon->data)) tmp += d(nd, 3);
  1308.         break;
  1309.     case 4:            /* death/disintegration */
  1310.         if(abs(type) != 24) {    /* death */
  1311.             if(is_undead(mon->data)) {
  1312.             shieldeff(mon->mx, mon->my);
  1313.             break;
  1314.             }
  1315.             type = -1; /* so they don't get saving throws */
  1316.         } else if (resists_disint(mon->data)) {
  1317.             shieldeff(mon->mx, mon->my);
  1318.             break;
  1319.         }
  1320.         tmp = mon->mhp+1;
  1321.         break;
  1322.     case 5:            /* lightning */
  1323.         if(resists_elec(mon->data)) {
  1324.             shieldeff(mon->mx, mon->my);
  1325.             break;
  1326.         }
  1327.         tmp = d(nd,6);
  1328.         {
  1329.             register unsigned rnd_tmp = rnd(50);
  1330.             mon->mcansee = 0;
  1331.             if((mon->mblinded + rnd_tmp) > 127)
  1332.                 mon->mblinded = 127;
  1333.             else mon->mblinded += rnd_tmp;
  1334.         }
  1335.         break;
  1336.     case 6:            /* poison */
  1337.         if(resists_poison(mon->data)) {
  1338.             shieldeff(mon->mx, mon->my);
  1339.             break;
  1340.         }
  1341.         tmp = d(nd,6);
  1342.         break;
  1343.     case 7:            /* acid */
  1344.         if(resists_acid(mon->data)) {
  1345.             shieldeff(mon->mx, mon->my);
  1346.             break;
  1347.         }
  1348.         tmp = d(nd,6);
  1349.         break;
  1350.     }
  1351.     if (type >= 0)
  1352.         if (resist(mon, (type < 10) ? WAND_SYM : '\0', 0, NOTELL)) tmp /= 2;
  1353.     mon->mhp -= tmp;
  1354.     return(tmp);
  1355. }
  1356.  
  1357. /*
  1358.  * burn scrolls and spell books on floor at position x,y
  1359.  * return the number of scrolls and spell books burned
  1360.  */
  1361. static int
  1362. burn_floor_paper(x, y)
  1363. int x, y;
  1364. {
  1365.     register struct obj *obj, *obj2;
  1366.     register int scrquan, i, cnt = 0;
  1367.  
  1368.     for(obj = level.objects[x][y]; obj; obj = obj2) {
  1369.         obj2 = obj->nexthere;
  1370.         /* Bug fix - KAA */
  1371. #ifdef SPELLS
  1372.         if((obj->olet == SCROLL_SYM || obj->olet == SPBOOK_SYM)) {
  1373. #else
  1374.         if(obj->olet == SCROLL_SYM) {
  1375. #endif
  1376.         if (obj->otyp == SCR_FIRE
  1377. #ifdef SPELLS
  1378.                     || obj->otyp == SPE_FIREBALL
  1379. #endif
  1380.             )
  1381.             continue;
  1382.         scrquan = obj->quan;
  1383.         for(i = 1; i <= scrquan ; i++)
  1384.             if(!rn2(3))  {
  1385.             cnt++;
  1386.             /* not useupf(), which charges */
  1387.             if (obj->quan > 1) obj->quan--;
  1388.             else delobj(obj);
  1389.             }
  1390.         }
  1391.     }
  1392.     return(cnt);
  1393. }
  1394.  
  1395. /* type == 0 to 9     : you shooting a wand */
  1396. /* type == 10 to 19   : you casting a spell */
  1397. /* type == 20 to 29   : you breathing as a monster */
  1398. /* type == -10 to -19   : monster casting spell */
  1399. /* type == -20 to -29 : monster breathing at you */
  1400. /* called with dx = dy = 0 with vertical bolts */
  1401. void
  1402. buzz(type,nd,sx,sy,dx,dy)
  1403. register int type, nd;
  1404. register xchar sx,sy;
  1405. register int dx,dy;
  1406. {
  1407.     int abstype = abs(type) % 10;
  1408.     register const char *fltxt = fl[abs(type)];
  1409.     struct rm *lev;
  1410.     register xchar lsx, lsy;
  1411. #ifdef __GNULINT__
  1412.     xchar range, olx=0, oly=0;
  1413. #else
  1414.     xchar range, olx, oly;
  1415. #endif
  1416.     struct monst *mon;
  1417.     register boolean bodyhit = FALSE;
  1418.     register boolean shopdoor = FALSE;
  1419.  
  1420.     if(u.uswallow) {
  1421.         register int tmp;
  1422.  
  1423.         if(type < 0) return;
  1424.         tmp = zhit(u.ustuck, type, nd);
  1425.         if(!u.ustuck)    u.uswallow = 0;
  1426.         else    pline("The %s rips into %s%s",
  1427.                 fltxt, mon_nam(u.ustuck), exclam(tmp));
  1428.         if (u.ustuck->mhp < 1)
  1429.             killed(u.ustuck);
  1430.         return;
  1431.     }
  1432.     if(type < 0) pru();
  1433.     range = rn1(7,7);
  1434.     Tmp_at2(-1, (int) dirlet(dx,dy));    /* open call */
  1435. #ifdef TEXTCOLOR
  1436.     Tmp_at2(-3, zapcolor[abstype]);
  1437. #endif
  1438.     while(range-- > 0) {
  1439.         lsx = sx; sx += dx;
  1440.         lsy = sy; sy += dy;
  1441.         if((lev = &levl[sx][sy])->typ) {
  1442.             if((cansee(lsx,lsy) && cansee(sx,sy)) ||
  1443.                 (!cansee(lsx,lsy) && cansee(sx,sy) &&
  1444.                  (IS_DOOR(lev->typ) || IS_ROOM(lev->typ))))
  1445.                 Tmp_at2(sx,sy);
  1446.         } else {
  1447.             int bounce = 0;
  1448.             if(cansee(sx-dx,sy-dy))
  1449.                 pline("The %s bounces!", fltxt);
  1450.             if(ZAP_POS(levl[sx][sy-dy].typ))
  1451.                 bounce = 1;
  1452.             if(ZAP_POS(levl[sx-dx][sy].typ)) {
  1453.                 if(!bounce || rn2(2)) bounce = 2;
  1454.             }
  1455.             switch(bounce){
  1456.             case 0:
  1457.                 dx = -dx;
  1458.                 dy = -dy;
  1459.                 continue;
  1460.             case 1:
  1461.                 dy = -dy;
  1462.                 sx -= dx;
  1463.                 break;
  1464.             case 2:
  1465.                 dx = -dx;
  1466.                 sy -= dy;
  1467.                 break;
  1468.             }
  1469.             Tmp_at2(-2,(int) dirlet(dx,dy));
  1470.             continue;
  1471.         }
  1472.         if(abstype == 1 /* fire */ &&
  1473.            (is_pool(sx,sy) || (lev->typ == ROOM && lev->icedpool))) {
  1474.             if(lev->typ == ROOM) {
  1475. #ifdef STUPID
  1476.             if (lev->icedpool == ICED_POOL)
  1477.                 lev->typ = POOL;
  1478.             else
  1479.                 lev->typ = MOAT;
  1480. #else
  1481.             lev->typ = (lev->icedpool == ICED_POOL ? POOL : MOAT);
  1482. #endif
  1483.             lev->icedpool = 0;
  1484.             pline("The ice crackles and melts.");
  1485.             mnewsym(sx,sy);
  1486.             } else {
  1487. #ifdef STRONGHOLD
  1488.             if(lev->typ != POOL) {    /* MOAT or DRAWBRIDGE_UP */
  1489.                 if(cansee(sx,sy))
  1490.                 pline("Some water evaporates.");
  1491.                 else if(flags.soundok)
  1492.                 You("hear a hissing sound.");
  1493.             } else {
  1494. #endif
  1495.                 register struct trap *ttmp;
  1496.  
  1497.                 range -= 3;
  1498.                 lev->typ = ROOM;
  1499.                 mnewsym(sx,sy);
  1500.                 if(cansee(sx,sy)) pline("The water evaporates.");
  1501.                 else if(flags.soundok)
  1502.                 You("hear a hissing sound.");
  1503.                 ttmp = maketrap(sx, sy, PIT);
  1504.                 ttmp->tseen = 1;
  1505. #ifdef STRONGHOLD
  1506.             }
  1507. #endif
  1508.             }
  1509.         }
  1510.         if(abstype == 3 /* cold */ && is_pool(sx,sy)) {
  1511.             boolean moat = (lev->typ != POOL);
  1512.  
  1513.             range -= 3;
  1514. #ifdef STRONGHOLD
  1515.             if(lev->typ == DRAWBRIDGE_UP) {
  1516.                 lev->drawbridgemask |= DB_ICE;
  1517.             } else {
  1518. #endif
  1519.                 lev->typ = ROOM;
  1520.                 lev->icedpool = (moat ? ICED_MOAT : ICED_POOL);
  1521. #ifdef STRONGHOLD
  1522.             }
  1523. #endif
  1524.             mnewsym(sx,sy);
  1525.             if(cansee(sx,sy)) {
  1526.                 if(moat)
  1527.                     pline("The moat is bridged with ice!");
  1528.                 else     pline("The water freezes.");
  1529.             } else if(flags.soundok)
  1530.                 You("hear a crackling sound.");
  1531.         }
  1532.         if(closed_door(sx, sy)) {
  1533.             range = 0;
  1534.             switch(abstype) {
  1535.             case 1:
  1536.                lev->doormask = D_NODOOR;
  1537.                mnewsym(sx,sy);
  1538.                if(cansee(sx,sy)) {
  1539.                 pline("The door is consumed in flames!");
  1540.                 prl(sx,sy);
  1541.                }
  1542.                else You("smell smoke.");
  1543.                if(type >= 0 && in_shop(sx, sy)) {
  1544.                 shopdoor = TRUE;
  1545.                 olx = sx;
  1546.                 oly = sy;
  1547.                }
  1548.                break;
  1549.             case 3:
  1550.                lev->doormask = D_NODOOR;
  1551.                mnewsym(sx,sy);
  1552.                if(cansee(sx,sy)) {
  1553.                 pline("The door freezes and shatters!");
  1554.                 prl(sx,sy);
  1555.                }
  1556.                else You("feel cold.");
  1557.                if(type >= 0 && in_shop(sx, sy)) {
  1558.                 shopdoor = TRUE;
  1559.                 olx = sx;
  1560.                 oly = sy;
  1561.                }
  1562.                break;
  1563.             case 4:
  1564.                lev->doormask = D_NODOOR;
  1565.                mnewsym(sx,sy);
  1566.                if(cansee(sx,sy)) {
  1567.                 pline("The door disintegrates!");
  1568.                 prl(sx,sy);
  1569.                }
  1570.                else if(flags.soundok)
  1571.                 You("hear a crashing sound.");
  1572.                if(type >= 0 && in_shop(sx, sy)) {
  1573.                 shopdoor = TRUE;
  1574.                 olx = sx;
  1575.                 oly = sy;
  1576.                }
  1577.                break;
  1578.             case 5:
  1579.                lev->doormask = D_BROKEN;
  1580.                mnewsym(sx,sy);
  1581.                if(cansee(sx,sy)) {
  1582.                 pline("The door splinters!");
  1583.                 prl(sx,sy);
  1584.                }
  1585.                else if(flags.soundok)
  1586.                 You("hear a crackling sound.");
  1587.                if(type >= 0 && in_shop(sx, sy)) {
  1588.                 shopdoor = TRUE;
  1589.                 olx = sx;
  1590.                 oly = sy;
  1591.                }
  1592.                break;
  1593.             default:
  1594.                if(cansee(sx,sy)) {
  1595.                    if (type >= 0 && type <= 9)
  1596.                    pline("The door absorbs your bolt!");
  1597.                    else if (type >= 10 && type <= 19)
  1598.                    pline("The door absorbs your spell!");
  1599. #ifdef POLYSELF
  1600.                    else if (type >= 20 && type <= 29)
  1601.                    pline("The door absorbs your blast!");
  1602. #endif
  1603.                    else if (type >= -19 && type <= -10)
  1604.                    pline("The door absorbs the spell!");
  1605.                    else
  1606.                    pline("The door absorbs the blast!");
  1607.                } else You("feel vibrations.");
  1608.                break;
  1609.             }
  1610.         }
  1611.         if(OBJ_AT(sx, sy) && abstype == 1)
  1612.             if(burn_floor_paper(sx,sy) && cansee(sx,sy))  {
  1613.                 mnewsym(sx,sy);
  1614.                 if(!Blind)
  1615.                 You("see a puff of smoke.");
  1616.             }
  1617.         if(MON_AT(sx, sy)){
  1618.             mon = m_at(sx,sy);
  1619.             /* Cannot use wakeup() which also angers the monster */
  1620.             mon->msleep = 0;
  1621.             if(mon->mimic) seemimic(mon);
  1622.             if(type >= 0) {
  1623.                 setmangry(mon);
  1624. #if defined(ALTARS) && defined(THEOLOGY)
  1625.                 if(mon->ispriest && in_temple(mon->mx, mon->my))
  1626.                 priesthit = TRUE;
  1627. #endif
  1628.             }
  1629.             if(rnd(20) < 18 + mon->data->ac) {
  1630.                 register int tmp = zhit(mon, type, nd);
  1631.                 if(mon->mhp < 1) {
  1632.                 if(type < 0) {
  1633.                     if(cansee(mon->mx,mon->my))
  1634.                       pline("%s is killed by the %s!",
  1635.                         Monnam(mon), fltxt);
  1636.                     mondied(mon);
  1637.                 } else
  1638.                     killed(mon);
  1639.                  } else
  1640.                 hit(fltxt, mon, exclam(tmp));
  1641.                 range -= 2;
  1642.             } else
  1643.                 miss(fltxt,mon);
  1644.         } else if(sx == u.ux && sy == u.uy) {
  1645.             nomul(0);
  1646.             if(rnd(20) < 18+u.uac) {
  1647.                 register int dam = 0;
  1648.                 range -= 2;
  1649.                 pline("The %s hits you!",fltxt);
  1650.                 if (Reflecting) {
  1651.                     if (!Blind) {
  1652.                     if(Reflecting & WORN_AMUL)
  1653.                         makeknown(AMULET_OF_REFLECTION);
  1654.                     else
  1655.                         makeknown(SHIELD_OF_REFLECTION);
  1656.             pline("But it reflects from your %s!",
  1657.                 (Reflecting & W_AMUL) ? "amulet" : "shield");
  1658.                     } else
  1659.             pline("For some reason you are not affected!");
  1660.                     if (dx) dx = -dx;
  1661.                     if (dy) dy = -dy;
  1662.                     shieldeff(sx, sy);
  1663.                 }
  1664.                 else switch(abstype) {
  1665.                 case 0:        /* magic missile */
  1666.                     if(Antimagic) {
  1667.                     shieldeff(sx, sy);
  1668.                     pline("The missiles bounce off!");
  1669.                     } else dam = d(nd,6);
  1670.                     break;
  1671.                 case 1:        /* fire */
  1672.                     if(Fire_resistance) {
  1673.                     shieldeff(sx, sy);
  1674.                     You("don't feel hot!");
  1675. #ifdef POLYSELF
  1676. #ifdef GOLEMS
  1677.                     ugolemeffects(AD_FIRE, d(nd, 6));
  1678. #endif /* GOLEMS */
  1679. #endif
  1680.                     } else dam = d(nd, 6);
  1681.                     while (1) {
  1682.                     switch(rn2(5)) {
  1683.                     case 0:
  1684.         if (!rust_dmg(uarmh, "leather helmet", 0, FALSE)) continue;
  1685.                         break;
  1686.                     case 1:
  1687.                         bodyhit = TRUE;
  1688.                         if (uarmc) break;
  1689.         if (uarm) (void)(rust_dmg(uarm, xname(uarm), 0, FALSE));
  1690.                         break;
  1691.                     case 2:
  1692.         if (!rust_dmg(uarms, "wooden shield", 0, FALSE)) continue;
  1693.                         break;
  1694.                     case 3:
  1695.         if (!rust_dmg(uarmg, "gloves", 0, FALSE)) continue;
  1696.                         break;
  1697.                     case 4:
  1698.         if (!rust_dmg(uarmf, "boots", 0, FALSE)) continue;
  1699.                         break;
  1700.                     }
  1701.                     break; /* Out of while loop */
  1702.                         }
  1703.                     if(!rn2(3) && bodyhit)
  1704.                     destroy_item(POTION_SYM, AD_FIRE);
  1705.                     if(!rn2(3) && bodyhit)
  1706.                     destroy_item(SCROLL_SYM, AD_FIRE);
  1707. #ifdef SPELLS
  1708.                     if(!rn2(5) && bodyhit)
  1709.                     destroy_item(SPBOOK_SYM, AD_FIRE);
  1710. #endif
  1711.                     break;
  1712.                 case 2:        /* sleep */
  1713.                     if(Sleep_resistance) {
  1714.                     shieldeff(u.ux, u.uy);
  1715.                     You("don't feel sleepy.");
  1716.                     } else nomul(-d(nd,25)); /* sleep ray */
  1717.                     break;
  1718.                 case 3:        /* cold */
  1719.                     if(Cold_resistance) {
  1720.                     shieldeff(sx, sy);
  1721.                     You("don't feel cold.");
  1722. #ifdef POLYSELF
  1723. #ifdef GOLEMS
  1724.                     ugolemeffects(AD_COLD, d(nd, 6));
  1725. #endif /* GOLEMS */
  1726. #endif
  1727.                     } else
  1728.                     dam = d(nd, 6);
  1729.                     if(!rn2(3))
  1730.                     destroy_item(POTION_SYM, AD_COLD);
  1731.                     break;
  1732.                 case 4:        /* death */
  1733.                     if(type == -24
  1734. #ifdef POLYSELF
  1735.                     || type == 24
  1736. #endif
  1737.                         ) { /* disintegration */
  1738.                     if (Disint_resistance) {
  1739.                         You("are not disintegrated.");
  1740.                         break;
  1741.                     } else if(uarms) {
  1742.                         (void) destroy_arm(uarms);
  1743.                         break;
  1744.                     } else if (uarm)  {
  1745.                         (void) destroy_arm(uarm);
  1746.                         break;
  1747.                     }
  1748.                     }
  1749. #ifdef POLYSELF
  1750.                     else if(is_undead(uasmon)) {
  1751.                     shieldeff(sx, sy);
  1752.                     You("seem unaffected.");
  1753.                     break;
  1754.                     }
  1755. #endif
  1756.                     u.uhp = -1;
  1757.                     break;
  1758.                 case 5:        /* lightning */
  1759.                     if (Shock_resistance) {
  1760.                     shieldeff(sx, sy);
  1761.                     You("aren't affected.");
  1762. #ifdef POLYSELF
  1763. #ifdef GOLEMS
  1764.                     ugolemeffects(AD_ELEC, d(nd, 6));
  1765. #endif /* GOLEMS */
  1766. #endif
  1767.                     } else
  1768.                     dam = d(nd, 6);
  1769.                     if(!rn2(3))
  1770.                     destroy_item(WAND_SYM, AD_ELEC);
  1771.                     if(!rn2(3))
  1772.                     destroy_item(RING_SYM, AD_ELEC);
  1773.                     break;
  1774.                 case 6:        /* poison */
  1775.                     poisoned("blast", A_DEX, "poisoned blast", 15);
  1776.                     break;
  1777.                 case 7:        /* acid */
  1778.                     pline("The acid burns!");
  1779.                     dam = d(nd,6);
  1780.                     if(!rn2(6)) corrode_weapon();
  1781.                     if(!rn2(6)) corrode_armor();
  1782.                     break;
  1783.                 }
  1784.                 losehp(dam,fltxt, KILLED_BY_AN);
  1785.             } else pline("The %s whizzes by you!",fltxt);
  1786.             if (abstype == 5 && !Blind) { /* LIGHTNING */
  1787.                     You("are blinded by the flash!");
  1788.                 make_blinded((long)d(nd,50),FALSE);
  1789.                 seeoff(0);
  1790.             }
  1791.             stop_occupation();
  1792.         }
  1793.         if(!ZAP_POS(lev->typ)) {
  1794.             int bounce = 0;
  1795.             uchar rmn;
  1796.             if(cansee(sx,sy)) pline("The %s bounces!", fltxt);
  1797.             range--;
  1798.             if(!dx || !dy || !rn2(20)){
  1799.                 dx = -dx;
  1800.                 dy = -dy;
  1801.             } else {
  1802.               if(ZAP_POS(rmn = levl[sx][sy-dy].typ) &&
  1803.                 (IS_ROOM(rmn) || ZAP_POS(levl[sx+dx][sy-dy].typ)))
  1804.                 bounce = 1;
  1805.               if(ZAP_POS(rmn = levl[sx-dx][sy].typ) &&
  1806.                 (IS_ROOM(rmn) || ZAP_POS(levl[sx-dx][sy+dy].typ)))
  1807.                 if(!bounce || rn2(2))
  1808.                     bounce = 2;
  1809.  
  1810.               switch(bounce){
  1811.               case 0:
  1812.                 dy = -dy;
  1813.                 dx = -dx;
  1814.                 break;
  1815.               case 1:
  1816.                 dy = -dy;
  1817.                 break;
  1818.               case 2:
  1819.                 dx = -dx;
  1820.                 break;
  1821.               }
  1822.               Tmp_at2(-2, (int) dirlet(dx,dy));
  1823.             }
  1824.         }
  1825.     }
  1826.     Tmp_at2(-1,-1);
  1827.     if(shopdoor) pay_for_door(olx, oly, abstype == 1 ? "burn away" :
  1828.                        abstype == 3 ? "shatter" :
  1829.                        abstype == 4 ? "disintegrate" :
  1830.                        "destroy");
  1831. }
  1832.  
  1833. void
  1834. rlocgold(gold)
  1835. register struct gold *gold;
  1836. {
  1837.     register int tx, ty, otx, oty;
  1838.     long val = gold->amount;
  1839.  
  1840.     otx = gold->gx;
  1841.     oty = gold->gy;
  1842.     do {
  1843.         tx = rn1(COLNO-3,2);
  1844.         ty = rn2(ROWNO);
  1845.     } while(!goodpos(tx,ty,(struct permonst *)0));
  1846.     freegold(g_at(otx,oty));
  1847.     mkgold(val, tx, ty);
  1848.     if(cansee(otx,oty))
  1849.         newsym(otx,oty);
  1850.     if(cansee(tx,ty))
  1851.         newsym(tx,ty);
  1852. }
  1853.  
  1854. void
  1855. rloco(obj)
  1856. register struct obj *obj;
  1857. {
  1858.     register int tx, ty, otx, oty;
  1859.  
  1860.     otx = obj->ox;
  1861.     oty = obj->oy;
  1862.     do {
  1863.         tx = rn1(COLNO-3,2);
  1864.         ty = rn2(ROWNO);
  1865.     } while(!goodpos(tx,ty,(struct permonst *)0));
  1866.     move_object(obj, tx, ty);
  1867.     mnewsym(otx, oty);
  1868.     if(cansee(otx,oty) && !vism_at(otx,oty) && !Blind &&
  1869.             (Invisible || u.ux != otx || u.uy != oty))
  1870.         newsym(otx,oty);
  1871.     mnewsym(tx, ty);
  1872.     if(cansee(tx,ty) && !vism_at(tx,ty) && !Blind &&
  1873.             (Invisible || u.ux != tx || u.uy != ty))
  1874.         newsym(tx,ty);
  1875. }
  1876.  
  1877. void
  1878. fracture_rock(obj)    /* fractured by pick-axe or wand of striking */
  1879. register struct obj *obj;           /* no texts here! */
  1880. {
  1881.     /* unpobj(obj); */
  1882.     obj->otyp = ROCK;
  1883.     obj->quan = 7 + rn2(60);
  1884.     obj->owt = weight(obj);
  1885.     obj->olet = GEM_SYM;
  1886.     obj->known = FALSE;
  1887.     obj->onamelth = 0;        /* no names */
  1888.     if(cansee(obj->ox,obj->oy))
  1889.         prl(obj->ox,obj->oy);
  1890. }
  1891.  
  1892. boolean
  1893. break_statue(obj)
  1894. register struct obj *obj;
  1895. {
  1896.     struct trap *trap;
  1897.  
  1898.     if(trap = t_at(obj->ox,obj->oy))
  1899.         if(obj->corpsenm == trap->pm)
  1900.         if(makemon(&mons[trap->pm], obj->ox, obj->oy)) {
  1901.             pline("Instead of shattering, the statue suddenly comes alive!");
  1902.             delobj(obj);
  1903.             deltrap(trap);
  1904.             return FALSE;
  1905.         }
  1906.     if (obj->spe) {
  1907.         struct obj *magazine;
  1908. #ifdef SPELLS
  1909.         magazine = mkobj_at(SPBOOK_SYM, obj->ox, obj->oy, TRUE);
  1910. #else
  1911.         magazine = mkobj_at(SCROLL_SYM, obj->ox, obj->oy, TRUE);
  1912. #endif
  1913.         magazine->blessed = obj->blessed;
  1914.         magazine->cursed = obj->cursed;
  1915.     }
  1916.     fracture_rock(obj);
  1917.     return TRUE;
  1918. }
  1919.  
  1920. const char *destroy_strings[] = {
  1921.     "freezes and shatters", "freeze and shatter", "shattered potion",
  1922.     "boils and explodes", "boil and explode", "boiling potion",
  1923.     "catches fire and burns", "catch fire and burn", "burning scroll",
  1924.     "catches fire and burns", "catch fire and burn", "burning book",
  1925.     "turns to dust and vanishes", "turn to dust and vanish", "",
  1926.     "breaks apart and explodes", "break apart and explode", "exploding wand"
  1927. };
  1928.  
  1929. void
  1930. destroy_item(osym, dmgtyp)
  1931. register int osym, dmgtyp;
  1932. {
  1933.     register struct obj *obj, *obj2;
  1934.     register int quan, i, cnt, dmg, xresist, skip;
  1935.     register int dindx;
  1936.     const char *mult;
  1937.  
  1938.     for(obj = invent; obj; obj = obj2) {
  1939.  
  1940.         obj2 = obj->nobj;
  1941.         if(obj->olet != osym) continue; /* test only objs of type osym */
  1942.         xresist = skip = 0;
  1943. #ifdef __GNULINT__
  1944.         quan = dmg = dindx = 0;
  1945. #endif
  1946.         switch(dmgtyp) {
  1947.         case AD_COLD:
  1948.             if(osym == POTION_SYM) {
  1949.             quan = obj->quan;
  1950.             dindx = 0;
  1951.             dmg = rnd(4);
  1952.             } else skip++;
  1953.                 break;
  1954.         case AD_FIRE:
  1955.             xresist = (Fire_resistance && obj->olet != POTION_SYM);
  1956.  
  1957.             if (obj->otyp == SCR_FIRE
  1958. #ifdef SPELLS
  1959.                     || obj->otyp == SPE_FIREBALL
  1960. #endif
  1961.                                 )
  1962.               skip++;
  1963.             quan = obj->quan;
  1964.             switch(osym) {
  1965.             case POTION_SYM:
  1966.                 dindx = 1;
  1967.                 dmg = rnd(6);
  1968.                 break;
  1969.             case SCROLL_SYM:
  1970.                 dindx = 2;
  1971.                 dmg = 1;
  1972.                 break;
  1973. #ifdef SPELLS
  1974.             case SPBOOK_SYM:
  1975.                 dindx = 3;
  1976.                 dmg = 1;
  1977.                 break;
  1978. #endif
  1979.             default:
  1980.                 skip++;
  1981.                 break;
  1982.             }
  1983.             break;
  1984.         case AD_ELEC:
  1985.             xresist = (Shock_resistance && obj->olet != RING_SYM);
  1986.             quan = obj->quan;
  1987.             switch(osym) {
  1988.             case RING_SYM:
  1989.                 if(obj->otyp == RIN_SHOCK_RESISTANCE)
  1990.                     { skip++; break; }
  1991.                 dindx = 4;
  1992.                 dmg = 0;
  1993.                 break;
  1994.             case WAND_SYM:
  1995.                 if(obj->otyp == WAN_LIGHTNING) { skip++; break; }
  1996.                 dindx = 5;
  1997.                 dmg = rnd(10);
  1998.                 break;
  1999.             default:
  2000.                 skip++;
  2001.                 break;
  2002.             }
  2003.             break;
  2004.         default:
  2005.             skip++;
  2006.             break;
  2007.         }
  2008.         if(!skip) {
  2009.         for(i = cnt = 0; i < quan; i++)
  2010.             if(!rn2(3)) cnt++;
  2011.  
  2012.         if(!cnt) continue;
  2013.         if(cnt == quan)    mult = "Your";
  2014.         else    mult = (cnt == 1) ? "One of your" : "Some of your";
  2015.         pline("%s %s %s!", mult, xname(obj),
  2016.             (cnt > 1) ? destroy_strings[dindx*3 + 1]
  2017.                   : destroy_strings[dindx*3]);
  2018.         if(osym == POTION_SYM && dmgtyp != AD_COLD)
  2019.             potionbreathe(obj);
  2020.         for(i = 0; i < cnt; i++) {
  2021.             if (obj->owornmask) setnotworn(obj);
  2022.             useup(obj);
  2023.         }
  2024.         if(dmg) {
  2025.             if(xresist)    You("aren't hurt!");
  2026.             else    losehp(dmg,
  2027.             (cnt==1) ? destroy_strings[dindx*3 + 2] :
  2028.                 (const char *)makeplural(destroy_strings[dindx*3 + 2]),
  2029.             (cnt==1) ? KILLED_BY_AN : KILLED_BY);
  2030.         }
  2031.         }
  2032.     }
  2033.     return;
  2034. }
  2035.  
  2036. int
  2037. destroy_mitem(mtmp, osym, dmgtyp)
  2038. register struct monst *mtmp;
  2039. register int osym, dmgtyp;
  2040. {
  2041.     register struct obj *obj, *obj2;
  2042.     register int quan, i, cnt, skip, tmp = 0;
  2043.     register int dindx;
  2044.  
  2045.     for(obj = mtmp->minvent; obj; obj = obj2) {
  2046.  
  2047.         obj2 = obj->nobj;
  2048.         if(obj->olet != osym) continue; /* test only objs of type osym */
  2049.         skip = 0;
  2050. #ifdef __GNULINT__
  2051.         quan = dindx = 0;
  2052. #endif
  2053.         switch(dmgtyp) {
  2054.         case AD_COLD:
  2055.             if(osym == POTION_SYM) {
  2056.             quan = obj->quan;
  2057.             dindx = 0;
  2058.             tmp++;
  2059.             } else skip++;
  2060.                 break;
  2061.         case AD_FIRE:
  2062.             if (obj->otyp == SCR_FIRE
  2063. #ifdef SPELLS
  2064.                     || obj->otyp == SPE_FIREBALL
  2065. #endif
  2066.                                 )
  2067.               skip++;
  2068.             quan = obj->quan;
  2069.             switch(osym) {
  2070.             case POTION_SYM:
  2071.                 dindx = 1;
  2072.                 tmp++;
  2073.                 break;
  2074.             case SCROLL_SYM:
  2075.                 dindx = 2;
  2076.                 tmp++;
  2077.                 break;
  2078. #ifdef SPELLS
  2079.             case SPBOOK_SYM:
  2080.                 dindx = 3;
  2081.                 tmp++;
  2082.                 break;
  2083. #endif
  2084.             default:
  2085.                 skip++;
  2086.                 break;
  2087.             }
  2088.             break;
  2089.         case AD_ELEC:
  2090.             quan = obj->quan;
  2091.             switch(osym) {
  2092.             case RING_SYM:
  2093.                 if(obj->otyp == RIN_SHOCK_RESISTANCE)
  2094.                     { skip++; break; }
  2095.                 dindx = 4;
  2096.                 break;
  2097.             case WAND_SYM:
  2098.                 if(obj->otyp == WAN_LIGHTNING) { skip++; break; }
  2099.                 dindx = 5;
  2100.                 tmp++;
  2101.                 break;
  2102.             default:
  2103.                 skip++;
  2104.                 break;
  2105.             }
  2106.             break;
  2107.         default:
  2108.             skip++;
  2109.             break;
  2110.         }
  2111.         if(!skip) {
  2112.         for(i = cnt = 0; i < quan; i++)
  2113.             if(!rn2(3)) cnt++;
  2114.  
  2115.         if(!cnt) continue;
  2116.         pline("%s's %s %s!", Monnam(mtmp), xname(obj),
  2117.             (cnt > 1) ? destroy_strings[dindx*3 + 1]
  2118.                   : destroy_strings[dindx*3]);
  2119.         for(i = 0; i < cnt; i++) m_useup(mtmp, obj);
  2120.         }
  2121.     }
  2122.     return(tmp);
  2123. }
  2124.  
  2125. /*ARGSUSED*/
  2126. int
  2127. resist(mtmp, olet, damage, tell)
  2128. register struct monst    *mtmp;
  2129. register char    olet;
  2130. register int    damage, tell;
  2131. {
  2132.     register int    resisted = 0;
  2133. #ifdef HARD
  2134.     register int    lev;
  2135.  
  2136.     switch(olet)  {
  2137.  
  2138.         case WAND_SYM:
  2139.             lev = 8;
  2140.             break;
  2141.  
  2142.         case SCROLL_SYM:
  2143.             lev = 6;
  2144.             break;
  2145.  
  2146.         case POTION_SYM:
  2147.             lev = 5;
  2148.             break;
  2149.  
  2150.         default:    lev = u.ulevel;
  2151.             break;
  2152.     }
  2153.  
  2154.     resisted = (rn2(100) - mtmp->m_lev + lev) < mtmp->data->mr;
  2155.     if(resisted) {
  2156.  
  2157.         if(tell) {
  2158.             shieldeff(mtmp->mx, mtmp->my);
  2159.             pline("%s resists!", canseemon(mtmp) ? Monnam(mtmp) : "It");
  2160.         }
  2161.         mtmp->mhp -= damage/2;
  2162.     } else
  2163. #endif
  2164.         mtmp->mhp -= damage;
  2165.  
  2166.     if(mtmp->mhp < 1) killed(mtmp);
  2167.     return(resisted);
  2168. }
  2169.  
  2170. void
  2171. makewish()
  2172. {
  2173.     char buf[BUFSZ];
  2174.     register struct obj *otmp;
  2175.     unsigned wishquan, mergquan;
  2176.     int tries = 0;
  2177.  
  2178. retry:
  2179.     You("may wish for an object.  What do you want? ");
  2180.     getlin(buf);
  2181.     if(buf[0] == '\033') buf[0] = 0;
  2182. /* Note: if they wished for and got a non-object successfully, such as gold,
  2183.  * otmp = &zeroobj
  2184.  */
  2185.     otmp = readobjnam(buf);
  2186.     if (!otmp) {
  2187.         pline("Nothing fitting that description exists in the game.");
  2188.         if (++tries < 5) goto retry;
  2189.         pline(thats_enough_tries);
  2190.         if (!(otmp = readobjnam((char *)0)))
  2191.         return; /* for safety; should never happen */
  2192.     }
  2193.     if (otmp != &zeroobj) {
  2194.         if (!Blind) otmp->dknown = 1; /* needed for merge to work */
  2195.         wishquan = otmp->quan;
  2196.         otmp = addinv(otmp);
  2197.         if(inv_cnt() > 52) {
  2198.             pline("Oops!  The %s to the floor!", aobjnam(otmp, "drop"));
  2199.             dropx(otmp);
  2200.         } else {
  2201.             mergquan = otmp->quan;
  2202.             otmp->quan = wishquan; /* to fool prinv() */
  2203.             prinv(otmp);
  2204.             otmp->quan = mergquan;
  2205.         }
  2206. #ifdef THEOLOGY
  2207.         u.ublesscnt += rn1(100,50);  /* the gods take notice */
  2208. #endif
  2209.     }
  2210. }
  2211.